//
//  GWRecommandsViewController.swift
//  GhostWorld
//
//  Created by Kam on 2018/4/2.
//  Copyright © 2018 LKGood. All rights reserved.
//

import UIKit
import SnapKit

class GWRecommendationsViewController: GWChildViewController {
  
  // MARK: - IBOutlets
  
  @IBOutlet private weak var bigRecommendationsContainer: UIView!
  @IBOutlet private weak var redButtonStackView: UIStackView!
  @IBOutlet private weak var latestPanel: TitledPanel!
  @IBOutlet private weak var bottomPanel: TitledPanel!
  
  // MARK: - Private vars
  
  private let bigRecommendationsView: GWBigRecommendationsView = .fromNib()
  private let albumRecommendationsView: GWAlbumRecommendationsView = .fromNib()
  private var isFirstLoaded = true
  
  // MARK: - Private methods
  
  override func prepareUI() {
    bigRecommendationsContainer.backgroundColor = .clear
    bigRecommendationsContainer.addSubview(bigRecommendationsView)
    bigRecommendationsView.snp.makeConstraints { maker in
      maker.leading.top.trailing.bottom.equalTo(0)
    }
    bigRecommendationsView.delegate = self
    
    latestPanel.snp.makeConstraints { maker in
      maker.top.equalTo(redButtonStackView.snp.bottom)
      maker.leading.equalTo(16)
      maker.trailing.equalTo(-16)
    }
    bottomPanel.snp.makeConstraints { maker in
      maker.top.equalTo(latestPanel.snp.bottom).offset(16)
      maker.leading.equalTo(16)
      maker.trailing.equalTo(-16)
      maker.height.equalTo(200)
      maker.bottom.equalTo(view).offset(-30)
    }
    bottomPanel.addSubview(albumRecommendationsView)
    albumRecommendationsView.snp.makeConstraints { maker in
      maker.top.equalTo(70)
      maker.leading.trailing.equalTo(0)
      maker.bottom.equalTo(-10)
    }
    albumRecommendationsView.delegate = self
  }
  
  private func loadData() {
    
    API.shared.requestAPI(APIURLStrings.gwRecommendations, method: .get, successCallback: { json in
      
      // top recommendations
      if let bigRecommendationsJSON = json["top_recommendations"].arrayObject as? [[String: Any]] {
        EntityManager.sync (
          type: Album.self,
          rawObject: bigRecommendationsJSON,
          operations: [.update, .insert, .insertRelationships, .updateRelationships, .deleteRelationships],
          completion: { error, albums in
            
            if error == nil {
              DispatchQueue.main.async {
                self.bigRecommendationsView.prepare(albums: albums!)
              }
            }
        })
      }
      
      // middle latest
      // MARK: - [TODO]: move logic to seperate view class
      if let latestJSON = json["latest"].arrayObject as? [[String: Any]] {
        EntityManager.sync (
          type: Album.self,
          rawObject: latestJSON,
          operations: [.update, .insert, .insertRelationships, .updateRelationships, .deleteRelationships],
          completion: { error, albums in
            
            if error == nil {
              DispatchQueue.main.async {
                self.latestPanel.subviews.forEach {
                  if type(of: $0) == AlbumListItem.self {
                    $0.removeFromSuperview()
                  }
                }
                var prevItem: AlbumListItem?
                for (index, album) in albums!.enumerated() {
                  let item: AlbumListItem = .fromNib()
                  item.delegate = self
                  item.prepare(album: album)
                  item.canDisplayTopLine = (index != 0)
                  
                  self.latestPanel.addSubview(item)
                  item.snp.makeConstraints { maker in
                    maker.leading.trailing.equalTo(0)
                    if index == 0 {
                      maker.top.equalTo(60)
                    } else {
                      maker.top.equalTo(prevItem!.snp.bottom)
                    }
                    maker.height.equalTo(AlbumListItem.defaultHeight)
                    if index == albums!.count - 1 {
                      maker.bottom.equalTo(self.latestPanel.snp.bottom).offset(-10)
                    }
                  }
                  prevItem = item
                }
              }
            }
        })
      }
      
      // album recommendations
      if let albumRecommendationsJSON = json["album_recommendations"].arrayObject as? [[String: Any]] {
        EntityManager.sync (
          type: Album.self,
          rawObject: albumRecommendationsJSON,
          operations: [.update, .insert, .insertRelationships, .updateRelationships, .deleteRelationships],
          completion: { error, albums in
            
            if error == nil {
              DispatchQueue.main.async {
                self.albumRecommendationsView.prepare(albums: albums!)
                
                UIView.animate(withDuration: 0.3) {
                  self.bigRecommendationsContainer.alpha = 1
                  self.redButtonStackView.alpha = 1
                  self.latestPanel.alpha = 1
                  self.bottomPanel.alpha = 1
                }
              }
            }
        })
      }
      
    }) { (message, code) in
      loggingPrint("[\(code)]: \(message)")
    }
  }
  
  private func showAlbumDetail(identifier: Int, canDisplayBasicInfo: Bool = true) {
    let storyboard = UIStoryboard(name: "ContentBrowsing", bundle: nil)
    let albumDetailViewController = storyboard.instantiateViewController(withIdentifier: "AlbumDetailViewController") as! AlbumDetailViewController
    albumDetailViewController.albumIdentifier = identifier
    albumDetailViewController.canDisplayBasicInfo = canDisplayBasicInfo
    navigationController?.pushViewController(albumDetailViewController, animated: true)
  }
  
  // MARK: - Public vars
  
  
  
  // MARK: - Lifecycle
  
  override func viewDidLoad() {
    super.viewDidLoad()
  }
  
  override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)
    
    if isFirstLoaded {
      bigRecommendationsContainer.alpha = 0
      redButtonStackView.alpha = 0
      latestPanel.alpha = 0
      bottomPanel.alpha = 0
    }
  }
  
  override func viewDidAppear(_ animated: Bool) {
    super.viewDidAppear(animated)
    
    if isFirstLoaded {
      loadData()
      isFirstLoaded = false
    }
  }
  
  override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.
  }
  
  // MARK: - IBActions
  
  @IBAction func showYingLiuYan() {
    showAlbumDetail(identifier: Album.DefaultAlbumIdentifer.yingLiuYan.rawValue, canDisplayBasicInfo: false)
  }
  
  @IBAction func showZaiRenJian() {
    showAlbumDetail(identifier: Album.DefaultAlbumIdentifer.zaiRenJian.rawValue, canDisplayBasicInfo: false)
  }
  
  @IBAction func showAnGe() {
    showAlbumDetail(identifier: Album.DefaultAlbumIdentifer.anGe.rawValue, canDisplayBasicInfo: false)
  }
  
  @IBAction func showReaders() {
    let storyboard = UIStoryboard(name: "ContentBrowsing", bundle: nil)
    let readersViewController = storyboard.instantiateViewController(withIdentifier: "ReadersViewController") as! ReadersViewController
    navigationController!.pushViewController(readersViewController, animated: true)
  }
  
  // MARK: - Public methods
  
}

// MARK: - GWBigRecommendationsViewDelegate

extension GWRecommendationsViewController: GWBigRecommendationsViewDelegate {
  func gwBigRecommendationsView(_ view: GWBigRecommendationsView, selectedWithAlbumIdentifier: Int) {
    showAlbumDetail(identifier: selectedWithAlbumIdentifier)
  }
}

// MARK: - AlbumListItemDelegate

extension GWRecommendationsViewController: AlbumListItemDelegate {
  func albumListItem(_ item: AlbumListItem, selectedWithAlbumIdentifier: Int) {
    showAlbumDetail(identifier: selectedWithAlbumIdentifier)
  }
}

extension GWRecommendationsViewController: GWAlbumRecommendationsViewDelegate {
  func gwAlbumRecommendationsView(_ item: GWAlbumRecommendationsView, selectedWithAlbumIdentifier: Int) {
    showAlbumDetail(identifier: selectedWithAlbumIdentifier)
  }
}
